package de.hsb.ai.learning;

import java.util.Collection;

import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

/**
 * Transition represents a state-transition.
 */
public class Transition extends Instance {

	private static final long serialVersionUID = -3743577650384476114L;

	//		private static final Attribute chosen = new Attribute("chosen");
	private static final Attribute chosen = new Attribute("chosen", State.BOOLEAN_VALUES);

	private static final FastVector ATTRIBUTES;

	static {
		ATTRIBUTES = new FastVector(State.ATTRIBUTES.size() * 2 + 1);
		ATTRIBUTES.appendElements(State.getAttributes(State.SOURCE_PREFIX));
		ATTRIBUTES.appendElements(State.getAttributes(State.TARGET_PREFIX));
		ATTRIBUTES.addElement(chosen);
	}

	public final int sourceIndex, targetIndex;
	
	private boolean m_chosen;

	public static Instances createInstances(String name) {
		Instances data = new Instances(name, ATTRIBUTES, 0);
		data.setClass(chosen);
		return data;
	}

	/**
	 * Creates an Instances object from a list of state-transitions.
	 * @param name the name of the relations set
	 * @param transitions list of transitions which is mapped to Instance objects
	 * @return the new Instances object
	 */
	public static Instances createInstances(String name, Collection<Transition> transitions) {
		if (transitions.isEmpty()) {
			throw new IllegalArgumentException("transitions must not be NULL");
		}

		Instances data = new Instances(name, ATTRIBUTES, transitions.size());
		for (Transition transition : transitions) {
			data.add(transition);
		}

		data.setClass(chosen);

		return data;
	}

	public Transition(State sourceState, State targetState) {
		super(ATTRIBUTES.size());

		sourceIndex = sourceState.idx;
		targetIndex = targetState.idx;

		// Copy states' values
		System.arraycopy(sourceState.values, 0, m_AttValues, 						 0, sourceState.values.length);
		System.arraycopy(targetState.values, 0, m_AttValues, sourceState.values.length, targetState.values.length);

		setWeight(sourceState.getWeight() * targetState.getWeight());
	}

	public Transition(State sourceState, State targetState, boolean chosen) {
		this(sourceState, targetState);
		setChosen(chosen);
	}

	public void setChosen(boolean value) {
		//			setChosen(State.valueOf(value));
		setChosen(State.BOOLEAN_VALUES.indexOf(Boolean.toString(m_chosen = value)));
	}

	private void setChosen(double value) {
		m_AttValues[ATTRIBUTES.indexOf(chosen)] = value;
	}

	public boolean isChosen() {
		return m_chosen;
	}

}